package com.gzhryc.pay.adaptation.weixin;

import com.gzhryc.common.config.PropertyTools;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.common.xml.XmlTools;
import com.gzhryc.pay.adaptation.weixin.enums.EWXPayBankCode;
import com.gzhryc.pay.adaptation.weixin.msg.WXReceivingInfo;
import com.gzhryc.pay.adaptation.weixin.msg.transfer.old.*;
import com.gzhryc.pay.enums.ReceivingMoneyType;
import com.gzhryc.pay.models.ITransferMoneyOrder;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Properties;

public class WXPayTransferMoneyOldService implements Serializable{

    static Logger log = Logger.getLogger(WXPayTransferMoneyOldService.class);

    DefaultWXPayConfig config;
    P12File p12File;

    public WXPayTransferMoneyOldService(){}

    public WXPayTransferMoneyOldService(Properties properties) {
        this.config = PropertyTools.build(properties).getObject(DefaultWXPayConfig.class);
        this.loadFiles();
    }

    public WXPayTransferMoneyOldService(DefaultWXPayConfig config) {
        this.config = config;
        this.loadFiles();
    }

    private void loadFiles(){
        if (StringUtils.isNotBlank(config.getCertificatePath())) {
            String path = config.getCertificatePath();
            if(path.endsWith("/")){
                path = path + config.getMchId() + "/apiclient_cert.p12";
            }else{
                path = path +"/" + config.getMchId() + "/apiclient_cert.p12";
            }
            File file = new File(path);
            if (file.exists()) {
                p12File = new P12File();
                p12File.setFile(file);
                p12File.setPassword(config.getCertificatePwd());
            }else {
                log.error("微信APPID：" + config.getAppId() + "的证书文件不存在，路径：" + file.getPath());
            }
        }else {
            log.error("未配置微信APPID：" + config.getAppId() + "的证书文件");
        }
    }

    /**
     * 企业转个人零钱
     * @param transferMoneyOrder
     * @return
     */
    public WXPayTransferMoneyPayV2Response transferMoneyToWallet(ITransferMoneyOrder transferMoneyOrder){
        CloseableHttpResponse response = null;
        String json = transferMoneyOrder.getReceivingInfo();
        if(StringUtils.isBlank(json)){
            log.error("转账到微信失败，未配置收款信息,tradeNo:" + transferMoneyOrder.getTradeNo());
            return null;
        }
        WXReceivingInfo info = null;
        if (ReceivingMoneyType.Account.index().equals(transferMoneyOrder.getReceivingType())) {
            info = JsonTools.fromJson(json, WXReceivingInfo.class);
            if (info == null || StringUtils.isBlank(info.getOpenid())) {
                log.error("转账到微信失败，未找到微信用户,tradeNo:" + transferMoneyOrder.getTradeNo());
                return null;
            }
        }else{
            log.error("此转账只支持转账至个人微信");
            return null;
        }
        try {
            CloseableHttpClient httpclient = WXHttpClient.getHttpClient(config.getAppId(),p12File);

            URI uri = new URIBuilder()
                    .setScheme("https")
                    .setHost("api.mch.weixin.qq.com")
                    .setPath("/mmpaymkttransfers/promotion/transfers")
                    .build();

            WXPayTransferMoneyPayV2Request request = new WXPayTransferMoneyPayV2Request();
            request.setPartner_trade_no(transferMoneyOrder.getTradeNo());
            request.setOpenid(info.getOpenid());
            request.setAmount(transferMoneyOrder.getMoney());
            request.setDesc(transferMoneyOrder.getNote());
            request.setMch_appid(this.config.getAppId());
            request.setMchid(this.config.getMchId());
            request.setSpbill_create_ip(this.config.getServerIp());
            //随即数
            request.setNonce_str(WXPayUtils.buildNonceStr());
            //生成签名
            request.setSign(WXPayUtils.buildSign(request, WXPayTransferMoneyPayV2Request.class,this.config.getPayKey()));

            log.info("转账请求参数：{{0:json}}",request);

            StringEntity strEntity = new StringEntity(XmlTools.changToXmlStr(request,false),
                    ContentType.create("application/xml", Consts.UTF_8));

            HttpPost httppost = new HttpPost(uri);
            httppost.setEntity(strEntity);

            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            if(entity != null){
                String str = EntityUtils.toString(entity, Charset.forName("UTF-8"));
                log.info("微信转账申请响应：" + str);
                WXPayTransferMoneyPayV2Response apiResp = XmlTools.changToObject(str, WXPayTransferMoneyPayV2Response.class, false);
                return apiResp;
            }
        } catch(Exception e){
            log.error(e.getMessage(),e);
        } finally {
            if(response != null){
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public WXPayTransferMoneyPayV2Response transferMoneyToBank(ITransferMoneyOrder transferMoneyOrder, Integer bankType, String bankCard, String bankName){
        CloseableHttpResponse response = null;
        try {
            CloseableHttpClient httpclient = WXHttpClient.getHttpClient(config.getAppId(),p12File);
            if(httpclient == null){
                log.error("转账到微信失败,tradeNo:" + transferMoneyOrder.getTradeNo());
                return null;
            }

            URI uri = new URIBuilder()
                    .setScheme("https")
                    .setHost("api.mch.weixin.qq.com")
                    .setPath("/mmpaysptrans/pay_bank")
                    .build();

            WXPayTransferMoneyBankPayV2Request request = new WXPayTransferMoneyBankPayV2Request();
            request.setPartner_trade_no(transferMoneyOrder.getTradeNo());
            request.setEnc_bank_no(bankCard);
            request.setEnc_true_name(bankName);
            request.setBank_code(EWXPayBankCode.note(bankType));
            request.setAmount(transferMoneyOrder.getMoney());
            request.setDesc(transferMoneyOrder.getNote());
            request.setMch_id(this.config.getMchId());
            //随即数
            request.setNonce_str(WXPayUtils.buildNonceStr());
            //生成签名
            request.setSign(WXPayUtils.buildSign(request, WXPayTransferMoneyBankPayV2Request.class,this.config.getPayKey()));

            StringEntity strEntity = new StringEntity(XmlTools.changToXmlStr(request,false),
                    ContentType.create("application/xml", Consts.UTF_8));

            HttpPost httppost = new HttpPost(uri);
            httppost.setEntity(strEntity);

            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            if(entity != null){
                String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
                log.info("微信转账申请响应：" + str);
                WXPayTransferMoneyPayV2Response result = XmlTools.changToObject(str, WXPayTransferMoneyPayV2Response.class, false);
                return result;
            }
        } catch(Exception e){
            log.error(e.getMessage(),e);
        } finally {
            if(response != null){
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 查询企业转个人余额的转账订单
     * @param transferMoneyOrder
     * @return
     */
    public WXPayTransferMoneyOrderV2Response queryTransferOrderToWallet(ITransferMoneyOrder transferMoneyOrder){
        CloseableHttpResponse response = null;
        try {
            CloseableHttpClient httpclient = WXHttpClient.getHttpClient(config.getAppId(),p12File);
            if(httpclient == null){
                log.error("转账到微信失败,tradeNo:" + transferMoneyOrder.getTradeNo());
                return null;
            }

            URI uri = new URIBuilder()
                    .setScheme("https")
                    .setHost("api.mch.weixin.qq.com")
                    .setPath("/mmpaymkttransfers/gettransferinfo")
                    .build();

            WXPayTransferMoneyOrderV2Request request = new WXPayTransferMoneyOrderV2Request();
            request.setPartner_trade_no(transferMoneyOrder.getTradeNo());
            request.setMch_id(this.config.getMchId());
            request.setAppid(this.config.getAppId());
            //随即数
            request.setNonce_str(WXPayUtils.buildNonceStr());
            //生成签名
            request.setSign(WXPayUtils.buildSign(request, WXPayTransferMoneyOrderV2Request.class,this.config.getPayKey()));

            StringEntity strEntity = new StringEntity(XmlTools.changToXmlStr(request,false),
                    ContentType.create("application/xml", Consts.UTF_8));

            HttpPost httppost = new HttpPost(uri);
            httppost.setEntity(strEntity);

            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            if(entity != null){
                String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
                log.info("微信转账查询响应：" + str);
                WXPayTransferMoneyOrderV2Response result = XmlTools.changToObject(str, WXPayTransferMoneyOrderV2Response.class, false);
                return result;
            }
        } catch(Exception e){
            log.error(e.getMessage(),e);
        } finally {
            if(response != null){
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public WXPayTransferMoneyBankOrderV2Response queryTransferOrderToBank(ITransferMoneyOrder transferMoneyOrder){
        CloseableHttpResponse response = null;
        try {
            CloseableHttpClient httpclient = WXHttpClient.getHttpClient(config.getAppId(),p12File);
            if(httpclient == null){
                log.error("转账到微信失败,tradeNo:" + transferMoneyOrder.getTradeNo());
                return null;
            }

            URI uri = new URIBuilder()
                    .setScheme("https")
                    .setHost("api.mch.weixin.qq.com")
                    .setPath("/mmpaymkttransfers/gettransferinfo")
                    .build();

            WXPayTransferMoneyBankOrderV2Request request = new WXPayTransferMoneyBankOrderV2Request();
            request.setPartner_trade_no(transferMoneyOrder.getTradeNo());
            request.setMch_id(this.config.getMchId());
            //随即数
            request.setNonce_str(WXPayUtils.buildNonceStr());
            //生成签名
            request.setSign(WXPayUtils.buildSign(request, WXPayTransferMoneyBankOrderV2Request.class,this.config.getPayKey()));

            StringEntity strEntity = new StringEntity(XmlTools.changToXmlStr(request,false),
                    ContentType.create("application/xml", Consts.UTF_8));

            HttpPost httppost = new HttpPost(uri);
            httppost.setEntity(strEntity);

            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            if(entity != null){
                String str = EntityUtils.toString(entity,Charset.forName("UTF-8"));
                log.info("微信转账查询响应：" + str);
                WXPayTransferMoneyBankOrderV2Response result = XmlTools.changToObject(str, WXPayTransferMoneyBankOrderV2Response.class, false);
                return result;
            }
        } catch(Exception e){
            log.error(e.getMessage(),e);
        } finally {
            if(response != null){
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
